#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMessageBox>
#include<weathertool.h>
#include<QPainter>
#include<QSizePolicy>
#define INCRENT   2 //温度每升高/降低1°，y轴坐标的增量
#define POINT_RADIUS 3 // 曲线描点的大小
#define TEXT_OFFSET_X 12
#define TEXT_OFFSET_Y 12
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);


    //设置主窗口的大小固定为 985*575
    setWindowFlag(Qt::FramelessWindowHint); //无边框
    setFixedSize(985,575); //固定窗口大小

    //构建右键菜单
    mExitMenu = new QMenu(this);
    mExitAct = new QAction();

    mExitAct->setText("退出");
    mExitAct->setIcon(QIcon(":/res/close.png"));
    mExitMenu->addAction(mExitAct);
    connect(mExitAct,&QAction::triggered,this,[=](){
    qApp->exit(0);
    });



    //天气状态图标
    mTypeMap.insert("暴雪",":/res/type/BaoXue.png");
    mTypeMap.insert("暴雨",":/res/type/BaoYu.png");
    mTypeMap.insert("大暴雨",":/res/type/DaBaoYu.png");
    mTypeMap.insert("大暴雨到特大暴雨",":/res/type/DaBaoYuDaoTeDaBaoYu.png");
    mTypeMap.insert("大到暴雪",":/res/type/DaDaoBaoXue.png");
    mTypeMap.insert("大雪",":/res/type/DaXue.png");
    mTypeMap.insert("大雨",":/res/type/DaYu.png");
    mTypeMap.insert("冻雨",":/res/type/DongYu.png");
    mTypeMap.insert("多云",":/res/type/DuoYun.png");
    mTypeMap.insert("晴转多云",":/res/type/DuoYun.png");
    mTypeMap.insert("多云转晴",":/res/type/DuoYun.png");
    mTypeMap.insert("小雨转多云",":/res/type/ZhenYu.png");
    mTypeMap.insert("小雨转晴",":/res/type/ZhenYu.png");
    mTypeMap.insert("中雨转晴",":/res/type/ZhenYu.png");
    mTypeMap.insert("雷阵雨",":/res/type/LeiZhenYu.png");
    mTypeMap.insert("雷阵雨伴有冰雹",":/res/type/LeiZhenYuBanYouBingBao.png");
    mTypeMap.insert("霾",":/res/type/Mai.png");
    mTypeMap.insert("强沙尘暴",":/res/type/QiangShaChenBao.png");
    mTypeMap.insert("晴",":/res/type/Qing.png");
    mTypeMap.insert("沙尘暴",":/res/type/ShaChenBao.png");
    mTypeMap.insert("特大暴雨",":/res/type/TeDaBaoYu.png");
    mTypeMap.insert("雾",":/res/type/Wu.png");
    mTypeMap.insert("小到中雪",":/res/type/XiaoDaoZhongXue.png");
    mTypeMap.insert("小到中雨",":/res/type/XiaoDaoZhongYu.png");
    mTypeMap.insert("中雨转小雨",":/res/type/DuoYun.png");
    mTypeMap.insert("小雪",":/res/type/XiaoXue.png");
    mTypeMap.insert("小雨",":/res/type/XiaoYu.png");
    mTypeMap.insert("雪",":/res/type/Xue.png");
    mTypeMap.insert("扬沙",":/res/type/YangSha.png");
    mTypeMap.insert("阴",":/res/type/Yin.png");
    mTypeMap.insert("雨",":/res/type/Yu.png");
    mTypeMap.insert("中雨转小雨",":/res/type/Yu.png");
    mTypeMap.insert("雨夹雪",":/res/type/YuJiaXue.png");
    mTypeMap.insert("阵雪",   ":/res/type/ZhenXue.png");
    mTypeMap.insert("阵雨",":/res/type/zhenyu.png");
    mTypeMap.insert("中到大雪",":/res/type/ZhongDaoDaXue.png");
    mTypeMap.insert("中到大雨",":/res/type/ZhongDaoDaYu.png");
    mTypeMap.insert("中雪",":/res/type/ZhongXue.png");
    mTypeMap.insert("中雨",":/res/type/ZhongYu.png");

    //将控件添加到控件数组

    //星期和日期
    mWeekList << ui->lblWeek0 << ui->lblWeek0_2 << ui->lblWeek0_3 << ui->lblWeek0_4 << ui->lblWeek0_5 << ui->lblWeek0_6;
    mDateList << ui->lblDate0 <<ui->lblDate0_2 << ui->lblDate0_3 << ui->lblDate0_4 << ui->lblDate0_5 << ui->lblDate0_6;
    // 天气和天气图标
    mTypeList << ui->lblType0 << ui->lblType1 << ui->lblType2 << ui->lblType3 << ui->lblType4 << ui->lblType5;
    mTypeIconList <<ui->lblTypeIcon0 << ui->lblTypeIcon1 << ui->lblTypeIcon2 << ui->lblTypeIcon3 << ui->lblTypeIcon4 << ui->lblTypeIcon5;
    // 天气指数
    mAqiList << ui->lblQuality0 << ui->lblQuality1 << ui->lblQuality2 << ui->lblQuality3<< ui->lblQuality4 << ui->lblQuality5;
    // 风向和风力
    mFxList << ui->lblFx0 << ui->lblFx1 << ui->lblFx2 << ui->lblFx3 << ui->lblFx4 << ui->lblFx5;
    mFlList << ui->lblFl0 << ui->lblFl1 << ui->lblFl2 << ui->lblFl3 << ui->lblFl4 << ui->lblFl5;


    //网络请求
    mNetworkAccessManager = new QNetworkAccessManager(this);
    //当http请求完毕，服务器返回数据时，mNetAccessManger 就会发射一个finished信号，进而调用onReplied槽函数
    connect(mNetworkAccessManager,&QNetworkAccessManager::finished,this,&MainWindow::onReplied);
    //直接在构造中，请求天气数据
    //101010100 是北京的城市编码
    getWeatherInfo("北京");

    // 设置搜索框隐式文字，(即占位符文本),占位符文本在输入框为空时显示，提示用户应输入的内容
     ui->lineEdit->setPlaceholderText("城市");
     //当用户按下Enter键时连接信号
    connect(ui->lineEdit,&QLineEdit::returnPressed,this,&MainWindow::onEnter);

    //给标签添加事件过滤器
    //参数为this，也就是当前窗口对象 MainWindow
    ui->lblHighCurve->installEventFilter(this);
    ui->lblLowCurve->installEventFilter(this);


}

MainWindow::~MainWindow()
{
    delete ui;
}
/*重写父类的虚函数,父类中默认的实现 是忽略右键菜单事件的,重写后，就可以处理右键菜单了
contextMenuEvent用于处理右键菜单事件。当用户在窗口中按下鼠标右键时，这个函数会被调用。*/
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    //弹出右键菜单
    mExitMenu->exec(QCursor::pos());
    /*exec 函数是 QMenu 类的一个成员函数，用于显示菜单并阻塞，直到用户选择了一个动作或取消菜单。它在给定的位置显示菜单。
    QCursor::pos() 返回当前光标的位置（屏幕坐标）。这里使用它来确保右键菜单在光标的位置弹出。*/
}

void MainWindow::mousePressEvent(QMouseEvent *event)
{
mOffset = event->globalPos() - this->pos();
}

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    this->move(event->globalPos()-mOffset);
}
//请求天气数据
void MainWindow::getWeatherInfo(QString cityName)
{

    WeatherTool tol;
    QString cityCode = tol.getCityCode(cityName);
    if(cityCode==nullptr)
        qDebug()<<"cityCode = 0";
    QString s = "http://v1.yiketianqi.com/api?unescape=1&version=v9&appid=36199855&appsecret=MT8Z6j3n&cityid="+cityCode;

    QUrl url(s);
    mNetworkAccessManager->get(QNetworkRequest(url));
}
//将获取到的JSON数据转化
void MainWindow::parseJson(QByteArray &byteArray)
{
    QJsonParseError err;
    QJsonDocument doc =  QJsonDocument::fromJson(byteArray,&err);

    if(err.error != QJsonParseError::NoError){
        return;
    }

    QJsonObject rootobj = doc.object();


    //1.解析今天
    QJsonArray TodayArray = rootobj.value("data").toArray();
    QJsonObject today = TodayArray[0].toObject();
    //解析时间
    QString d = rootobj.value("update_time").toString();
    mToday.week = today.value("week").toString();
    d += mToday.week;
    mToday.date = d;

    mToday.city = rootobj.value("city").toString();
    mToday.wendu = today.value("tem").toString();
    mToday.shidu = today.value("humidity").toString();
    mToday.weatype = today.value("wea").toString();

    mToday.high = today.value("tem1").toString();
    mToday.low = today.value("tem2").toString();

    //解析风向、风力
    mToday.fx =today.value("win").toArray().at(0).toString();
    mToday.fl = today.value("win_speed").toString();
    //pm2.5
    QJsonObject aqi = rootobj.value("aqi").toObject();
    mToday.pm25 = aqi.value("pm25").toString();
    //污染指数
    mToday.quality = today.value("air_level").toString();
    //穿衣指数
    QJsonArray index_Array = today.value("index").toArray();
    QJsonObject objdressing = index_Array[3].toObject();
    QString s = objdressing.value("title").toString()+
            "："+objdressing.value("level").toString()+objdressing.value("desc").toString();
    //qDebug()<<"s="<<s;
    mToday.dressing_index = s;
    //qDebug()<<"objdressing.value("").toString()="<<objdressing.value("title").toString();

    //2.解析6日天气
    QJsonArray dataArray = rootobj.value("data").toArray();
    for(int i =0;i<6;i++)
    {
        QJsonObject objday = dataArray[i].toObject();
        mday[i].week = objday.value("week").toString();
        mday[i].date = objday.value("date").toString().right(5);
        mday[i].wea_type =  objday.value("wea").toString();
        mday[i].wea_img =  objday.value("wea_img").toString();
        mday[i].air_level = objday.value("air_level").toString();
        mday[i].fx = objday.value("win").toArray().at(0).toString();
        mday[i].fl = objday.value("win_speed").toString();

        mday[i].high = objday.value("tem1").toString();
        mday[i].low = objday.value("tem2").toString();

    }
    updateUI();
    //更新温度曲线
    //调用update()函数会标记控件需要重绘。
    ui->lblHighCurve->update();
    ui->lblLowCurve->update();

}

void MainWindow::updateUI()
{
 //更新日期和城市
 QString dates = (QDateTime::fromString(mToday.date.left(10),"yyyy-mm-dd").
                     toString("yyyy/mm/dd")+" "+ mToday.date.right(11));
 ui->lblDate->setText("  "+dates);
 ui->lblCity->setText(mToday.city);

 // 更新今天数据
 QPixmap pix(mTypeMap.value(mday[0].wea_type));
 ui->lbltodaytype_ui->setPixmap(pix);
 ui->lblTemp->setText((mToday.wendu+"°"));
//天气状态
ui->lblType->setText(mToday.weatype);


//温度区间

ui->lblLowHigh->setText((mToday.low)+"°~"+(mToday.high)+"°");
ui->lblWindFl->setText(mToday.fl);
ui->lblWindFx->setText(mToday.fx);

ui->lblpm25->setText((mToday.pm25));
ui->lblshidu->setText(mToday.shidu);
ui->lblQuality->setText(mToday.quality);
//穿衣指数
ui->lbldressing_index->setText(mToday.dressing_index);
qDebug()<<"穿衣指数"<<mToday.dressing_index;
 //更新六天
for(int i =0;i<6;i++)
{

    mWeekList[i]->setText( mday[i].week);
    mDateList[i]->setText(mday[i].date);
    //天气状态
    mTypeList[i]->setText(mday[i].wea_type);
    QPixmap pix(mTypeMap.value(mday[i].wea_type));
    mTypeIconList[i]->setPixmap(pix);

    //空气质量
    mAqiList[i]->setText(mday[i].air_level);
    if(mday[i].air_level=="优")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(121,184,0);");
    else if(mday[i].air_level=="良")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(255,187,2);");
    if(mday[i].air_level=="轻度污染")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(255,87,97);");
    if(mday[i].air_level=="中度污染")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(235,17,27);");
    if(mday[i].air_level=="重度污染")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(170,0,0);");
    if(mday[i].air_level=="严重污染")
    mAqiList[i]->setStyleSheet("backGround-color: rgb(110,0,0);");
    mFxList[i]->setText(mday[i].fx);
    mFlList[i]->setText(mday[i].fl);



    //设置控件文本的居中
    mWeekList[i]->setAlignment(Qt::AlignCenter);
    mDateList[i]->setAlignment(Qt::AlignCenter);
    mTypeList[i]->setAlignment(Qt::AlignCenter);
    mAqiList[i]->setAlignment(Qt::AlignCenter);
    mFxList[i]->setAlignment(Qt::AlignCenter);
    mFlList[i]->setAlignment(Qt::AlignCenter);

}
}

//消息过滤，主要用于重绘子控件，过滤Paint事件
bool MainWindow::eventFilter(QObject *watched, QEvent *event)
{

    //绘制最高温度曲线
    if(watched == ui->lblHighCurve && event->type() == QEvent::Paint){
       // qDebug()<<"绘制最高温度曲线";
        paintHighCurve();
    }
    //绘制最低温度曲线
    if(watched == ui->lblLowCurve && event->type() == QEvent::Paint){
       // qDebug()<<"绘制最低温度曲线";
        paintLowCurve();
    }
    return QWidget::eventFilter(watched,event);
}

void MainWindow::paintHighCurve()
{
  QPainter painter(ui->lblHighCurve);
  //抗锯齿
  painter.setRenderHint(QPainter::Antialiasing,true);
  //x的坐标
  int Pointx[6] = {0};
  int Pointy[6] = {0};
  int average =0 ;
  int sum = 0;
  for (int i =0 ;i<6;i++) {
      Pointx[i] = mWeekList[i]->pos().x()+ mWeekList[i]->width()/2;
      //high温度的总值
     sum+=mday->high.toUInt();//toUInt() 方法将字符串转换为无符号整数，如果转换失败，默认返回 0。
  }
    //y的坐标
    //high温度的平均值
      average = sum/6;
      int yCenter = ui->lblHighCurve->height()/2;
      for (int i =0 ;i<6;i++) {
         Pointy[i] = yCenter-((mday[i].high.toInt()-average)*INCRENT);

      }


 //绘制

 QPen pen = painter.pen();
 pen.setWidth(1);
 pen.setColor(QColor(255,170,0));
 painter.setPen(pen);
 painter.setBrush(QColor(255,170,0));    //设置画刷内部填充的颜色
  //画点、写文本
  for(int i =0;i<6;i++)
  {    //                    圆心               半径
    painter.drawEllipse(Pointx[i],Pointy[i],POINT_RADIUS,POINT_RADIUS);
    //显示温度文本             文本坐标
    painter.drawText(Pointx[i]-TEXT_OFFSET_X,Pointy[i]-TEXT_OFFSET_Y,mday[i].high+"°");

  }
  for(int i =0;i<5;i++)
  {
      if(i==0) // 第一条线为虚线，设置画笔样式为Qt::DashLine
      {
          pen.setStyle(Qt::DashLine);
          painter.setPen(pen);
      }
      else// 其余线为实线，设置画笔样式为Qt::SolidLine
      {
          pen.setStyle(Qt::SolidLine);
          painter.setPen(pen);
      }
      //                  起始坐标          终点坐标
      painter.drawLine(Pointx[i],Pointy[i],Pointx[i+1],Pointy[i+1]);
  }

}

void MainWindow::paintLowCurve()
{

  //x的坐标
  int Pointx[6] = {0};
  int Pointy[6] = {0};
  int average =0 ;
  int sum = 0;
  for (int i =0 ;i<6;i++) {
      Pointx[i] = mWeekList[i]->pos().x()+ mWeekList[i]->width()/2;
      //low温度的总值
     sum+=mday->low.toUInt();

  }
    //y的坐标
    //low温度的平均值
      average = sum/6;
      int yCenter = ui->lblLowCurve->height()/2;
      for (int i =0 ;i<6;i++) {
         Pointy[i] = yCenter-((mday[i].low.toInt()-average)*INCRENT);

      }

 //绘制              指定的绘画设备
 QPainter painter(ui->lblLowCurve);
 //抗锯齿
 painter.setRenderHint(QPainter::Antialiasing,true);
 QPen pen = painter.pen();
 pen.setWidth(1);
 pen.setColor(QColor(0,255,255));
 painter.setPen(pen);
 painter.setBrush(QColor(0,255,255));    //设置画刷内部填充的颜色
  //画点、写文本
  for(int i =0;i<6;i++)
  {
    painter.drawEllipse(Pointx[i],Pointy[i],POINT_RADIUS,POINT_RADIUS);
    //显示温度文本
    painter.drawText(Pointx[i]-TEXT_OFFSET_X,Pointy[i]-TEXT_OFFSET_Y,mday[i].low+"°");

  }
  for(int i =0;i<5;i++)
  {
      if(i==0)
      {
          pen.setStyle(Qt::DashLine);
          painter.setPen(pen);
      }
      else
      {
          pen.setStyle(Qt::SolidLine);
          painter.setPen(pen);
      }
      painter.drawLine(Pointx[i],Pointy[i],Pointx[i+1],Pointy[i+1]);
  }
}

void MainWindow::onReplied(QNetworkReply *reply)
{

//响应码为200，代表请求成功
    int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    if(reply->error()!=QNetworkReply::NoError||status_code!=200)
    {
       QMessageBox::warning(this,"天气","请求数据失败！",QMessageBox::Ok);
    }
    else
    {
        //请求成功返回数据
        QByteArray byteArray = reply->readAll();
        parseJson(byteArray);
        //qDebug()<<"aead all："<<byteArray.data();
    }
    reply->deleteLater();
}

//点击搜索按钮槽函数
void MainWindow::on_pushButtont_sosuo_clicked()
{
    QString s = ui->lineEdit->text();
    getWeatherInfo(s);
}
//按下Enter键触发搜索
void MainWindow::onEnter()
{
    QString s = ui->lineEdit->text();
    getWeatherInfo(s);
}
